package Inference;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ReasonerRegistry;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.util.iterator.Filter;

public class OntologyAccess {
	private static String nameSpace = "";
	private static Model model = ModelFactory.createOntologyModel();
	private static OntModel ontModel = null;

        
        public static void setNameSpace(String namespace){
            
            OntologyAccess.nameSpace=namespace;
        }
        
        public static void setModel(Model model){
            
            OntologyAccess.model=model;
        }
        
	public static void printIndividuals(String ontClassName) {
		OntClass ontClass = ontModel.getOntClass(nameSpace + ontClassName);
		ExtendedIterator<? extends OntResource> individuals = ontClass
				.listInstances();
		while (individuals.hasNext()) {
			OntResource d = (OntResource) individuals.next();
			System.out.println(d.getURI());
		}
	}

	public static ExtendedIterator<? extends OntResource> getIndividuals (
			String ontClassName)throws Exception {
		OntClass ontClass = ontModel.getOntClass(nameSpace + ontClassName);
		ExtendedIterator<? extends OntResource> individuals = ontClass
				.listInstances();
		return individuals;
	}

	public static List<String> getJuegosJugadosUsuario(String usuario) {
		List<String> result = new ArrayList<String>();
				
		OntResource ind = ontModel.getOntResource(nameSpace + usuario);
		System.out.println(ind);
		
		Property property = ontModel.getProperty(nameSpace + "ha_jugado");
		
		StmtIterator it = ind.listProperties(property);
	
		while (it.hasNext()) {
			Statement s = (Statement) it.next();
			Resource resource = s.getObject().asResource();
			result.add(resource.getLocalName());
		}
		return result;
	}
	
	public static List<String> getJuegosCompradosUsuario(String usuario) {
		List<String> result = new ArrayList<String>();
				
		OntResource ind = ontModel.getOntResource(nameSpace + usuario);
		
		Property property = ontModel.getProperty(nameSpace + "ha_comprado");
		
		StmtIterator it = ind.listProperties(property);
	
		while (it.hasNext()) {
			Statement s = (Statement) it.next();
			Resource resource = s.getObject().asResource();
			result.add(resource.getLocalName());
		}
		return result;
	}

	public static List<String> getPropiedadesJuegosObject(String juego, String propiedad) {
               List<String> result = new ArrayList<>();
                               
               OntResource ind = ontModel.getOntResource(nameSpace + juego);
               
               Property property = ontModel.getProperty(nameSpace + propiedad);
               
               StmtIterator it = ind.listProperties(property);
       
               while (it.hasNext()) {
                       Statement s = (Statement) it.next();
                       Resource resource = s.getObject().asResource();
                       result.add(resource.getLocalName());
               }
               return result;
       }
        
       public static List<String> getPropiedadesJuegosData(String juego, String propiedad) {
               List<String> result = new ArrayList<String>();
                               
               OntResource ind = ontModel.getOntResource(nameSpace + juego);
               
               Property property = ontModel.getProperty(nameSpace + propiedad);
               
               StmtIterator it = ind.listProperties(property);
       
               while (it.hasNext()) {
                       Statement s = (Statement) it.next();
                       Literal literal = s.getObject().asLiteral() ;
                       result.add(literal.getLexicalForm() );
               }
               return result;
       }
	
	public static List<String> getJuegos() throws Exception {
		ExtendedIterator<? extends OntResource> individuals= getIndividuals("Juego");
		List<String> juegos = new ArrayList<String>();
		while (individuals.hasNext()) {
			Individual ind = individuals.next().asIndividual();  //.getSubject().as(Individual.class);
			juegos.add(ind.getLocalName());
		}
		
		return juegos;
	}
        public static List<String> getConsolas() throws Exception {
		ExtendedIterator<? extends OntResource> individuals= getIndividuals("Consola");
		List<String> consolas = new ArrayList<String>();
		while (individuals.hasNext()) {
			Individual ind = individuals.next().asIndividual();  //.getSubject().as(Individual.class);
			consolas.add(ind.getLocalName());
		}
		
		return consolas;
	}
	public static List<String> getGeneros() throws Exception{
		ExtendedIterator<? extends OntResource> individuals= getIndividuals("Genero");
		List<String> generos = new ArrayList<String>();
		while (individuals.hasNext()) {
			Individual ind = individuals.next().asIndividual();
			generos.add(ind.getLocalName());
		}
		
		return generos;

	}
	

	public static List<String> getSymptoms(String diseaseName) {
		List<String> result = new ArrayList<String>();
		OntResource disease = ontModel.getOntResource(nameSpace + diseaseName);
		Property property = ontModel.getProperty(nameSpace + "evidenceOf");
		// find out the resources that link to the instance
		for (StmtIterator stmts = ontModel.listStatements(null, property,
				disease); stmts.hasNext();) {
			Individual ind = stmts.next().getSubject().as(Individual.class);
			// show the properties of this individual
			result.add(ind.getLocalName());
		}
		return result;
	}
	
	public static boolean isSymptom(String symptomName){
		OntResource symptom = ontModel.getOntResource(nameSpace + symptomName);
		if(symptom !=null){
			return true;
		}
		return false;
	}
	
	public static Boolean loadOntology(String filename) {
		InputStream in;
		try {
			in = new FileInputStream(
					filename);// or any
																	// windows
																	// path
			model.read(in, "");
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		nameSpace = model.getNsPrefixURI("");
		Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
		reasoner = reasoner.bindSchema(model);
		OntModelSpec ontModelSpec = OntModelSpec.OWL_DL_MEM;
		ontModelSpec.setReasoner(reasoner);
		ontModel = ModelFactory.createOntologyModel(ontModelSpec, ontModel);
		return true;
	}
        
        public static void prepareOntology(){
            Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
            reasoner = reasoner.bindSchema(model);
            OntModelSpec ontModelSpec = OntModelSpec.OWL_DL_MEM;
            ontModelSpec.setReasoner(reasoner);
            ontModel = ModelFactory.createOntologyModel(ontModelSpec, ontModel);
            
        }                
        
        
}
